package service

import (
	"awesomeProject/app/model"
	"awesomeProject/app/request"
	"awesomeProject/app/response"
	"awesomeProject/global"
	"awesomeProject/util"
	"context"
	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"strconv"
	"strings"
	"time"
)

type CommentSrv struct{}

func (r *CommentSrv) Pagination(req request.CommentPagination, shopIds []uint, operator model.User) response.Resp {
	filter := bson.D{}
	if req.ShopId != 0 {
		filter = append(filter, bson.E{Key: "shopId", Value: req.ShopId})
	} else {
		if req.CompanyId != 0 && operator.SuperAdmin {
			var accounts []model.Account
			//err := global.Gorm.Where("company_id=? and status=1", req.CompanyId).Find(&accounts).Error
			//禁用的店铺里的数据，也展示出来
			err := global.Gorm.Where("company_id=?", req.CompanyId).Find(&accounts).Error
			if err != nil {
				return response.ErrQuery
			}
			shopIds = []uint{}
			for _, account := range accounts {
				shopIds = append(shopIds, account.ShopId)
			}
		}
		if len(shopIds) > 0 {
			filter = append(filter, bson.E{Key: "shopId", Value: bson.M{"$in": shopIds}})
		}
	}
	if req.KeywordVal != "" {
		if req.KeywordType == "itemId" {
			KeywordVal, _ := strconv.Atoi(req.KeywordVal)
			filter = append(filter, bson.E{Key: "itemId", Value: KeywordVal})
		} else if req.KeywordType == "itemNo" {
			filter = append(filter, bson.E{Key: "itemNo", Value: req.KeywordVal})
		} else if req.KeywordType == "skuId" {
			KeywordVal, _ := strconv.Atoi(req.KeywordVal)
			filter = append(filter, bson.E{Key: "skuId", Value: KeywordVal})
		} else if req.KeywordType == "skuNo" {
			filter = append(filter, bson.E{Key: "skuNo", Value: req.KeywordVal})
		} else if req.KeywordType == "title" {
			// filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": "" + req.KeywordVal + ""}})
			filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": primitive.Regex{Pattern: ".*"+strings.Trim(req.KeywordVal, " ")+".*", Options: "i"}}})
		}
	}
	if req.Title != "" {
		filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": primitive.Regex{Pattern: ".*"+strings.Trim(req.Title, " ")+".*", Options: "i"}}})
	}
	if req.Date != "" {
		dateRange := strings.Split(req.Date, "~")
		sDate, _ := time.ParseInLocation("2006-01-02", dateRange[0], time.Local)
		eDate, _ := time.ParseInLocation("2006-01-02", dateRange[1], time.Local)
		filter = append(filter, bson.E{Key: "commentTimeStamp", Value: bson.M{"$gte": sDate.Unix() * 1000, "$lte": eDate.Unix() * 1000}})
	}
	if req.Dimension == 1 { // 好评
		filter = append(filter, bson.E{Key: "dimension", Value: bson.M{"$in": []int{1, 4}}})
	} else if req.Dimension == 2 { // 差评
		filter = append(filter, bson.E{Key: "dimension", Value: 2})
	}

	match := bson.D{{"$match", filter}}
	sort := bson.D{{"$sort", bson.D{{"commentTimeStamp", -1}}}}
	offset := (req.PageIndex - 1) * req.PageSize
	skip := bson.D{{"$skip", offset}}
	limit := bson.D{{"$limit", req.PageSize}}
	cursor, err := global.MongoDB.Collection("comments").Aggregate(context.TODO(), mongo.Pipeline{match, sort, skip, limit})
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	var comments []model.Comment
	if err = cursor.All(context.TODO(), &comments); err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	if len(comments) == 0 {
		return response.OK.WithData(map[string]interface{}{
			"total": 0,
			"list":  comments,
		})
	}
	total, err := global.MongoDB.Collection("comments").CountDocuments(context.TODO(), filter)
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}

	var commentsExtra []model.CommentWithExtra
	if len(comments) > 0 {
		for _, comment := range comments {
			commentExtra := model.CommentWithExtra{}
			util.StructAssign(&commentExtra, &comment)
			//fmt.Println(commentExtra.ShopId)
			//fmt.Println(commentExtra.ItemId)
			where := bson.D{
				{"shopId", commentExtra.ShopId},
				{"itemId", commentExtra.ItemId},
			}
			var overmerchant model.OrderMerchantList
			err2 := global.MongoDB.Collection("merchant_list").FindOne(context.TODO(), where).Decode(&overmerchant)
			if err2 == nil {
				commentExtra.PreCreatedAtString = overmerchant.PreCreatedAtString
			}
			commentsExtra = append(commentsExtra, commentExtra)
		}
	}

	return response.OK.WithData(map[string]interface{}{
		"total": total,
		//"list":  comments,
		"list":  commentsExtra,
	})
}

func (r *CommentSrv) CommentDimensionCount(req request.CommentDimensionCount, shopIds []uint, operator model.User) response.Resp {
	filter := bson.D{}
	if req.ShopId != 0 {
		filter = append(filter, bson.E{Key: "shopId", Value: req.ShopId})
	} else {
		if req.CompanyId != 0 && operator.SuperAdmin {
			var accounts []model.Account
			//err := global.Gorm.Where("company_id=? and status=1", req.CompanyId).Find(&accounts).Error
			//禁用的店铺里的数据，也展示出来
			err := global.Gorm.Where("company_id=?", req.CompanyId).Find(&accounts).Error
			if err != nil {
				return response.ErrQuery
			}
			shopIds = []uint{}
			for _, account := range accounts {
				shopIds = append(shopIds, account.ShopId)
			}
		}
		if len(shopIds) > 0 {
			filter = append(filter, bson.E{Key: "shopId", Value: bson.M{"$in": shopIds}})
		}
	}
	if req.KeywordVal != "" {
		if req.KeywordType == "itemId" {
			filter = append(filter, bson.E{Key: "itemId", Value: req.KeywordVal})
		} else if req.KeywordType == "itemNo" {
			filter = append(filter, bson.E{Key: "itemId", Value: req.KeywordVal})
		} else if req.KeywordType == "skuId" {
			filter = append(filter, bson.E{Key: "itemId", Value: req.KeywordVal})
		} else if req.KeywordType == "skuNo" {
			filter = append(filter, bson.E{Key: "itemId", Value: req.KeywordVal})
		} else if req.KeywordType == "title" {
			// filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": "" + req.KeywordVal + ""}})
			filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": primitive.Regex{Pattern: ".*"+strings.Trim(req.KeywordVal, " ")+".*", Options: "i"}}})
		}
	}
	if req.Title != "" {
		filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": primitive.Regex{Pattern: ".*"+strings.Trim(req.Title, " ")+".*", Options: "i"}}})
	}
	if req.Date != "" {
		dateRange := strings.Split(req.Date, "~")
		sDate, _ := time.Parse("2006-01-02", dateRange[0])
		eDate, _ := time.Parse("2006-01-02", dateRange[1])
		filter = append(filter, bson.E{Key: "date", Value: bson.M{"$gte": sDate, "$lte": eDate}})
	}
	//统计汇总，无需过滤
	//if req.Dimension == 1 { // 好评
	//	filter = append(filter, bson.E{Key: "dimension", Value: bson.M{"$in": []int{1, 4}}})
	//} else if req.Dimension == 2 { // 差评
	//	filter = append(filter, bson.E{Key: "dimension", Value: 2})
	//}

	match := bson.D{{"$match", filter}}
	group := bson.D{{
		"$group", bson.D{
			{"_id", "$dimension"},
			{"count", bson.M{"$sum": 1}},
		},
	}}
	cursor, err := global.MongoDB.Collection("comments").Aggregate(context.TODO(), mongo.Pipeline{match, group})
	if err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}
	var counts []model.CommentDimensionCount
	if err = cursor.All(context.TODO(), &counts); err != nil {
		return response.ErrQuery.SetMsg(err.Error())
	}

	resp := model.FCommentDimensionCount{}
	resp.ShopId = req.ShopId
	resp.Dimension = req.Dimension
	for _, res := range counts {
		resp.All += res.Count
		if res.ID == 1 {
			resp.Good += res.Count
		} else if res.ID == 2 {
			resp.Bad += res.Count
		} else if res.ID == 4 {
			resp.Good += res.Count
		}
	}

	return response.OK.WithData(resp)
}

func (r *CommentSrv) Export(ctx *gin.Context, req request.CommentExport) error {
	filter := bson.D{}
	if req.ShopId != 0 {
		filter = append(filter, bson.E{Key: "shopId", Value: req.ShopId})
	}
	if req.KeywordVal != "" {
		if req.KeywordType == "itemId" {
			KeywordVal, _ := strconv.Atoi(req.KeywordVal)
			filter = append(filter, bson.E{Key: "itemId", Value: KeywordVal})
		} else if req.KeywordType == "itemNo" {
			filter = append(filter, bson.E{Key: "itemNo", Value: req.KeywordVal})
		} else if req.KeywordType == "skuId" {
			KeywordVal, _ := strconv.Atoi(req.KeywordVal)
			filter = append(filter, bson.E{Key: "skuId", Value: KeywordVal})
		} else if req.KeywordType == "skuNo" {
			filter = append(filter, bson.E{Key: "skuNo", Value: req.KeywordVal})
		} else if req.KeywordType == "title" {
			// filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": "" + req.KeywordVal + ""}})
			filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": primitive.Regex{Pattern: ".*"+strings.Trim(req.KeywordVal, " ")+".*", Options: "i"}}})
		}
	}
	if req.Title != "" {
		filter = append(filter, bson.E{Key: "title", Value: bson.M{"$regex": primitive.Regex{Pattern: ".*"+strings.Trim(req.Title, " ")+".*", Options: "i"}}})
	}
	if req.Date != "" {
		dateRange := strings.Split(req.Date, "~")
		sDate, _ := time.ParseInLocation("2006-01-02", dateRange[0], time.Local)
		eDate, _ := time.ParseInLocation("2006-01-02", dateRange[1], time.Local)
		filter = append(filter, bson.E{Key: "commentTimeStamp", Value: bson.M{"$gte": sDate.Unix() * 1000, "$lte": eDate.Unix() * 1000}})
	}
	if req.Dimension == 1 { // 好评
		filter = append(filter, bson.E{Key: "dimension", Value: bson.M{"$in": []int{1, 4}}})
	} else if req.Dimension == 2 { // 差评
		filter = append(filter, bson.E{Key: "dimension", Value: 2})
	}

	match := bson.D{{"$match", filter}}
	sort := bson.D{{"$sort", bson.D{{"commentTimeStamp", -1}}}}
	cursor, err := global.MongoDB.Collection("comments").Aggregate(context.TODO(), mongo.Pipeline{match, sort})
	if err != nil {
		return err
	}
	var comments []model.Comment
	if err = cursor.All(context.TODO(), &comments); err != nil {
		return err
	}

	//定义首行标题
	dataKey := make([]map[string]string, 0)
	dataKey = append(dataKey, map[string]string{
		"key":    "title",
		"title":  "商品名称",
		"width":  "120",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "attr",
		"title":  "款式",
		"width":  "50",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "skuId",
		"title":  "Fordeal SKU",
		"width":  "50",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "itemId",
		"title":  "商品ID",
		"width":  "50",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "itemNo",
		"title":  "商品货号",
		"width":  "50",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "itemNo",
		"title":  "商家SKU",
		"width":  "50",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "sn",
		"title":  "销售单号",
		"width":  "50",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "comment",
		"title":  "评价",
		"width":  "50",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "createdAt",
		"title":  "评价时间",
		"width":  "50",
		"is_num": "0",
	})
	dataKey = append(dataKey, map[string]string{
		"key":    "tag",
		"title":  "标签",
		"width":  "50",
		"is_num": "0",
	})

	//填充数据
	data := make([]map[string]interface{}, 0)
	if len(comments) > 0 {
		for _, v := range comments {
			data = append(data, map[string]interface{}{
				"title":     v.Title,
				"attr":      v.Attr,
				"skuId":     v.SkuId,
				"sn":        v.Sn,
				"itemId":    v.ItemId,
				"itemNo":    v.ItemNo,
				"skuNo":     v.SkuNo,
				"comment":   v.Comment["content"],
				"tag":       v.Tag,
				"createdAt": util.UnixToStr(int64(v.CommentTimeStamp)/1000, "2006-01-02 15:04:05"),
			})
		}
	}
	util.NewMyExcel().ExportToWeb(dataKey, data, ctx)

	return nil
}
